package tech.dongliang.shiro;

import com.hazelcast.core.Hazelcast;
import com.hazelcast.core.HazelcastInstance;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.ShiroException;
import org.apache.shiro.cache.Cache;
import org.apache.shiro.cache.CacheException;
import org.apache.shiro.cache.CacheManager;
import org.apache.shiro.cache.MapCache;
import org.apache.shiro.util.Destroyable;
import org.apache.shiro.util.Initializable;

import java.util.Map;

@Slf4j
@Data
public class SpringCacheManagerWrapper implements CacheManager, Initializable, Destroyable {
    private static HazelcastInstance hazelcastInstance;

    @Override
    public <K, V> Cache<K, V> getCache(String name) throws CacheException {
        //returned map is a ConcurrentMap
        Map<K, V> map = hazelcastInstance.getMap(name);
        return new MapCache<>(name, map);
    }

    public HazelcastInstance hazelcastInstance() {
        if (hazelcastInstance == null) {
            hazelcastInstance = Hazelcast.newHazelcastInstance();
        }
        return hazelcastInstance;
    }

    @Override
    public void init() throws ShiroException {
        hazelcastInstance();
    }

    @Override
    public void destroy() throws Exception {
        try {
            hazelcastInstance.getLifecycleService().shutdown();
        } catch (Throwable t) {
            if (log.isWarnEnabled()) {
                log.warn("Unable to cleanly shutdown implicitly created HazelcastInstance.  " +
                        "Ignoring (shutting down)...", t);
            }
        } finally {
            hazelcastInstance = null;
        }
    }

}
